#include "script/ScriptDocumentOperation.h"
#include "simodo/inout/reporter/StreamReporter.h"

using namespace simodo;

variable::Value makeSimodoCommandResult(
        const std::u16string &       id,
        const std::u16string &       title,
        lsp::SimodoCommandReportType type,
        const std::u16string &       text
) {
    return variable::Object{{
        { u"id",    id },
        { u"title", title },
        { u"type",  static_cast<int64_t>(type) },
        { u"text",  inout::encodeSpecialChars(text) },
}};
}

variable::Value makeSimodoCommandResponse(const std::u16string & uri, const variable::Value & commandResult) {
    return variable::Object{{
        { u"uri",           uri },
        { u"commandResult", commandResult }
    }};
}

variable::Value ScriptDocumentOperation::produceSimodoCommandResponse(const std::u16string & command_name, std::u16string text) const
{
    if (command_name.empty() || command_name != execution_report)
        return {};


    interpret::SemanticDataCollector_null semantic_data;
    std::ostringstream outputStream;
    inout::StreamReporter reporter(outputStream);

    executeModuleManager(
            *getInputSupplier(text),
            reporter,
            semantic_data,
            interpret::InterpretType::Preview,
            getInitialContractFile()
    );

    return makeSimodoCommandResponse(
            /* uri           = */ inout::toU16(_doc.file_name()),
            /* commandResult = */ makeSimodoCommandResult(
                       /* id    = */ u"grammar-report",
                       /* title = */ u"'" + fs::path(_doc.file_name()).filename().u16string() + u"' " + command_name,
                       /* type  = */ lsp::SimodoCommandReportType::plainText,
                       /* text  = */ inout::toU16(outputStream.str())
                )
    );
}